import pandas as pd
from openai import OpenAI
from sklearn.metrics import accuracy_score
import ollama
import numpy as np
import pandas as pd
from warnings import simplefilter
import streamlit as lit
import langroid.language_models as lm
import langroid as lr

# simplefilter(action="ignore", category=pd.errors.PerformanceWarning)
# simplefilter(action="ignore", category=FutureWarning)
# #ignore ValueError
# simplefilter(action="ignore", category=ValueError)
API_key = 'apikey'
client = OpenAI(api_key=API_key)

# question = input('Enter the question you want to ask the model: ')


def openai_result(query, df):
    model = ai(API_key)
    response = openai.Completion.create(
        engine="gpt-4o-mini",  # or "gpt-4" if available
        prompt=query,
        max_tokens=200,
        temperature=0.3  # 0 makes it deterministic, you can adjust for more creativity
    )
    print(response)
    result = eval(response)
    return result
    
    
    


def local_llm_result(model,query,df):
    code = ollama.generate(prompt=query, model=model)
    print(code['response'][3:-4])

    result = eval(code['response'][3:-4])
    
    # result = sdf.chat(query+'If graphing, you must return a sentence: Graphing completed')
    return result

def truth_value(df,query):
    result = eval(query)
    return result


if __name__ == '__main__':
    # initializations
    filename = 'data/cleaned_data.csv'
    df = pd.read_csv(filename, low_memory=False)

    # column_ids = [84, 101, 114, 166, 183, 187, 188, 190, 194, 199, 204, 206, 276]
    # column_names = df.columns[column_ids]
    # for col_name in column_names:
    #     if col_name in df.columns:
    #         df[col_name] = df[col_name].astype(str).replace('nan', 'NULL')
    
    


    # query construction
    # mode = input('Enter running mode: 0 is from file, 1 is manual')



    # print(result_llm)
    query_to_openai = 'I want you to be the prompt engingeer and edit the prompt I will give you based on the column I give you. Can you must replace the related content with the exact column name. To be remind about only return the edited content don\'t say something like here\'s the edited prompt, I only want the result. I want the prompt to be accuracy as well and envolve with all the necessary key words, try to use minimal calls to the columns. When calling column names put a quatation mark around the column name.'
    
    # query_to_openai += 'filepath:data/cleaned_data.csv'
    column_names = df.columns
    column_values = ''
    prohibited = ['CrashId']
    for col_name in df.columns:
        if col_name not in prohibited:
            column_values += col_name + ':' + ', '.join(map(str, df[col_name].unique())) + '\n'

    questions = []
    with open('questions.txt', 'r') as f:
        questions = f.readlines()
    for question in questions:
        query_to_openai += 'Column names:' + ', '.join(column_names)

        response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[
                {
                    "role": "system",
                    "content": query_to_openai
                },
                {
                    "role": "user",
                    "content": question 
                }
            ],
            temperature=0.7,
            max_tokens=1024,
            top_p=1
        )

        message = response.choices[0].message.content
        print("Edited prompt:", message)
        pre_prompting = 'I want you to generate code, CODE ONLY! The code must not contain comments. use pandas functions as possible, keep code clean, df is already defined. Do not define a function put everything down. Directly call on it. Return the result in a format of a string in the end.'
        # pre_prompting += ', '.join(column_names)
        message_to_execute = pre_prompting + message
        question = pre_prompting + question   

        # message += 'the data file name is'+filename
        # pre_prompt = 'I want you to repeat what I say:'
        # message = pre_prompt + message

        ### The result generation Factory:
        try:
            model = "llama3.1:latest"
            llama_result = local_llm_result(model,message_to_execute,df)
            if 'Unfortunately' in llama_result:
                llama_result = 'FAILED'
        except:
            llama_result = 'FAILED'
        try:
            model = "deepseek-coder-v2:latest"
            deepseek_result = local_llm_result(model,message_to_execute,df)
            if 'Unfortunately' in deepseek_result:
                deepseek_result = 'FAILED'
        except:
            deepseek_result = 'FAILED'
        try:
            model = "starcoder2:latest"
            starcoder_result = local_llm_result(model,message_to_execute,df)
            if 'Unfortunately' in starcoder_result:
                starcoder_result = 'FAILED'
        except:
            starcoder_result = 'FAILED'
        try:
            model = "gemma2:27b"
            gemma_result = local_llm_result(model,message_to_execute,df)
            if 'Unfortunately' in gemma_result:
                gemma_result = 'FAILED'
        except:
            gemma_result = 'FAILED'
        try:
            chatgpt_result = openai_result(message_to_execute,df)
            if 'Unfortunately' in chatgpt_result:
                chatgpt_result = 'FAILED'
        except:
            chatgpt_result = 'FAILED'
        with open('results.csv', 'a') as f:
            f.write(f'{message_to_execute}\n{question}')
            f.write(f'{llama_result},{deepseek_result},{starcoder_result},{gemma_result},{chatgpt_result}\n')
        try:
            model = "llama3.1:latest"
            llama_result = local_llm_result(model,question,df)
            if 'Unfortunately' in llama_result:
                llama_result = 'FAILED'
        except:
            llama_result = 'FAILED'
        try:
            model = "deepseek-coder-v2:latest"
            deepseek_result = local_llm_result(model,question,df)
            if 'Unfortunately' in deepseek_result:
                deepseek_result = 'FAILED'
        except:
            deepseek_result = 'FAILED'
        try:
            model = "starcoder2:latest"
            starcoder_result = local_llm_result(model,question,df)
            if 'Unfortunately' in starcoder_result:
                starcoder_result = 'FAILED'
        except:
            starcoder_result = 'FAILED'
        try:
            model = "gemma2:27b"
            gemma_result = local_llm_result(model,question,df)
            if 'Unfortunately' in gemma_result:
                gemma_result = 'FAILED'
        except:
            gemma_result = 'FAILED'
        try:
            chatgpt_result = openai_result(question,df)
            if 'Unfortunately' in chatgpt_result:
                chatgpt_result = 'FAILED'
        except:
            chatgpt_result = 'FAILED'
        with open('results.csv', 'a') as f:
            f.write(f'{llama_result},{deepseek_result},{starcoder_result},{gemma_result},{chatgpt_result}\n')
            f.write('\n')
        ### End of factory

        
        

        